const utils = {
  /** 克隆 */
  cloneOBJ: (data: any) => JSON.parse(JSON.stringify(data)),
  /** 去重 */
  dupRemove: <T>(d: T[]) : T[] => Array.from(new Set(d)),
  /** 随机 */
  randomByNum: (max: number, min: number = 0) => Math.floor(Math.random() * (max + 1) + min),
  /** 随机 */
  randomByList: <T>(lib: T[]): T => lib[Math.floor(Math.random() * lib.length)],
  /** 随机 */
  randomByListPro: <T>(lib: T[]): {e: T, i: number} => {
    const i = Math.floor(Math.random() * lib.length)
    const e = lib[i]
    return {e, i}
  },
  sumByNum: (arr: number[]): number => {
    if (arr.length === 0) return 0
    else if (arr.length === 1) return arr[0]
    else return arr.reduce((a, b) => a + b)
  },
  /** 组合算法，从m中选取n个数进行组合
   * @param data
   * @param size
   */
  choose<T>(data: T[], size: number) {
    var allResult: T[][] = [];

    const runner = (arr: T[], size: number, result: T[]) => {
      var arrLen = arr.length;
      if (size > arrLen) {
        return;
      }
      if (size == arrLen) {
        allResult.push(([] as T[]).concat(result, arr))
      } else {
        for (let i = 0; i < arrLen; i++) {
          var newResult = ([] as any[]).concat(result);
          newResult.push(arr[i]);

          if (size == 1) {
            allResult.push(newResult);
          } else {
            var newArr = ([] as any[]).concat(arr);
            newArr.splice(0, i + 1);
            runner(newArr, size - 1, newResult);
          }
        }
      }
    }

    runner(data, size, []);

    return allResult;
  },
  /**
   * 类型判断
   * @param payload 判断的值
   * @param type 判断的类型 支持 function\date\blob等判断
   * @returns
   */
  typeof(payload: any, type: string) {
    return Object.prototype.toString.call(payload).toLocaleLowerCase().includes(`object ${type.toLocaleLowerCase()}`)
  },
  encryMobile: (str: string) => `${str.slice(0, 3)} **** ${str.slice(7)}`,
  format(date: number | string | Date, fmt: string = 'yyyy/MM/dd hh:mm:ss') {
    date = new Date(date)

    if (isNaN(date.getTime())) {
      throw Error('请检查传入时间！')
    }

    const o = {
      'M+': date.getMonth() + 1, // 月份
      'd+': date.getDate(), // 日
      'h+': date.getHours(), // 小时
      'm+': date.getMinutes(), // 分
      's+': date.getSeconds(), // 秒
      'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
      'S': date.getMilliseconds(), // 毫秒
    };

    if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, String(date.getFullYear()).substr(4 - RegExp.$1.length)); }
    for (const k in o) {
      const _ = k as keyof typeof o
      if (new RegExp('(' + k + ')').test(fmt)) {
        fmt = fmt.replace(RegExp.$1, String(RegExp.$1.length === 1 ? o[_] : ('00' + o[_]).substr(String(o[_]).length)));
      }
    }
    return fmt;
  },
  /** 获取日期结束时间
   * @example 2022/01/01 -> 2022/01/01 23:59:59
   * @param {Date} time
   * @returns Date
   */
  getDayEnd(time = new Date()) {
    return new Date(`${time.format('yyyy/MM/dd 23:59:59')}`)
  },
  /** 获取日期开始时间
   * @example 2022/01/01 -> 2022/01/01 00:00:00
   * @param {Date} time
   * @returns Date
   */
  getDayStart(time = new Date()) {
    return new Date(`${time.format('yyyy/MM/dd 00:00:00')}`)
  },
  fmtObject<T = Record<string, any>>(obj: T): T {
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        if (obj[key] === null || obj[key] === undefined) {
          delete obj[key]
        }
      }
    }

    return obj
  },
  sleep(delay: number): Promise<void> {
    return new Promise(resolve => {
      const timer = setTimeout(() => {
        resolve()
        clearTimeout(timer)
      }, delay)
    });
  }
}

Date.prototype.format = function(fmt = 'yyyy/MM/dd') {
  return utils.format(this, fmt)
}

export default utils
